package com.itheima.app.interceptor;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.itheima.domain.db.User;
import com.itheima.domain.db.UserFreezing;
import com.itheima.domain.db.UserInfo;
import com.itheima.service.db.FreezingService;
import com.itheima.service.db.UserInfoService;
import com.itheima.util.ConstantUtil;
import com.itheima.util.JwtUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.Duration;
import java.util.Date;
import java.util.Map;

@Component
public class TokenInterceptor implements HandlerInterceptor {

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Reference
    private UserInfoService userInfoService;
    @Reference
    private FreezingService freezingService;

    //进入controller之前
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("Authorization");
        //如果token为空 返回失败
        if (StringUtils.isEmpty(token)) {
            System.out.println("token为空");
            response.setStatus(401);
            return false;
        }
        //从Redis中查询token是否存在
        String s = redisTemplate.opsForValue().get(ConstantUtil.USER_TOKEN + token);
        if (StringUtils.isEmpty(s)) {
            System.out.println("token不存在");
            response.setStatus(401);
            return false;
        }

        //解析token，如果解析失败返回错误，解析成功进行token续期并放行
        try {
            Map map = JwtUtil.parseToken(token);
            User user = BeanUtil.mapToBean(map, User.class, true);
            UserHolder.set(user);
            //判断用户是否封冻
            Long userId = user.getId();
            UserInfo userInfo = userInfoService.findById(userId);
            UserFreezing userFreezing = freezingService.findFreezing(userId, userInfo.getFreezingRange());
            if (userFreezing != null && userInfo.getUserStatus().equals("2")) {
                if (userFreezing.getFreezingRange() == 1) {
                    if (userFreezing.getFreezingTime() == 1 && new Date().getTime() <= DateUtil.offsetDay(userFreezing.getFreezing(), 3).getTime()) {
                        redisTemplate.delete(ConstantUtil.USER_TOKEN + token);
                    } else if (userFreezing.getFreezingTime() == 2 && new Date().getTime() <= DateUtil.offsetDay(userFreezing.getFreezing(), 7).getTime()) {
                        redisTemplate.delete(ConstantUtil.USER_TOKEN + token);
                    } else if (userFreezing.getFreezingTime() == 3) {
                        redisTemplate.delete(ConstantUtil.USER_TOKEN + token);
                    }
                }
            } else {
                if (userInfo.getFreezingRange() == null) {
                    redisTemplate.opsForValue().set(ConstantUtil.USER_TOKEN + token, user.getPhone(), Duration.ofDays(30));
                    //放行
                    return true;
                }
                if ("1".equals(userInfo.getFreezingRange())) {
                    userInfo.setUserStatus(1 + "");//改为正常状态
                    userInfoService.updateUserInfo(Integer.parseInt(userId+""),userInfo);
                    //token续期
                    redisTemplate.opsForValue().set(ConstantUtil.USER_TOKEN + token, user.getPhone(), Duration.ofDays(30));
                    return true;
                }
            }


        } catch (Exception e) {
            System.out.println("解析token失败");
            response.setStatus(401);
            return false;
        }
        return true;
    }

    //页面渲染完毕之后
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        UserHolder.remove();
    }
}
